home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / Origami / Sources / src / keybind / keybind.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  20.4 KB  |  892 lines

  1. /*{{{}}}*/
  2. /*{{{  #includes*/
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <sys/types.h>
  7. #include <unistd.h>
  8. #include <limits.h>
  9. #include <stdio.h>
  10. #include <signal.h>
  11. #ifndef NO_GETOPT_H
  12. #  include <getopt.h>
  13. #endif
  14.  
  15. #define KEYBIND_C
  16.  
  17. #include <h/getmsg.h>
  18. #include "keybind.h"
  19. #include <h/rcformat.h>
  20. #include <h/envvar_str.h>
  21. #include <lib/ori_rc_lib.h>
  22. #include <lib/ori_add_lib.h>
  23. /*}}}  */
  24.  
  25. /*{{{  variables*/
  26. private unsigned char std_basename[]=STD_BASENAME;
  27. private unsigned char bnd_name[BIND_NAME_LEN]="Origami";
  28. public boolean commenting=False,
  29.                do_opt=False,
  30.                sorting=False,
  31.                warning=False;
  32. public int verbose_level= -1,
  33.            t_counter=0,
  34.            tl_counter=0,
  35.            m_counter=0;
  36. public LOC_FILE rc={ 0,False,0 };
  37. public LOC_FILE in={ 0,False,0 };
  38. public LOC_FILE ref={ 0,False,0 };
  39. public LOC_FILE ref_no={ 0,False,0 };
  40. public unsigned char *dest_mac=0;
  41. public char *lib_path;
  42. #ifndef STD_FILTER
  43. #   define STD_FILTER 0
  44. #endif
  45. private unsigned char *source_filter=STD_FILTER;
  46. #ifndef STD_TOP_FILTER
  47. #   define STD_TOP_FILTER 0
  48. #endif
  49. private unsigned char *top_filter=STD_TOP_FILTER;
  50. private boolean rcref=False;
  51. private LOC_FILE bnd={ 0,False,0 };
  52. private struct RC_STR
  53.  { unsigned char *text;
  54.    struct RC_STR *next;
  55.    TOKEN ad;
  56.  } *rc_strings=0;
  57. private int rc_str_count=0;
  58. private int rc_str_lg=0;
  59. /*}}}  */
  60.  
  61. /*{{{  display usage*/
  62. private void do_usage(void)
  63. {
  64.   fprintf(stderr,M_USAGE);
  65.   fprintf(stderr,M_MICE);
  66.   show_mice(stderr);
  67.   fputc('\n',stderr);
  68. }
  69. /*}}}  */
  70. /*{{{  completebase*/
  71. private unsigned char *completebase(unsigned char *s, unsigned char *filebase, unsigned char *t)
  72. {
  73.   ustrcpy(s,filebase);
  74.   ustrcat(s,t);
  75.  
  76.   return(s);
  77. }
  78. /*}}}  */
  79. /*{{{  open source-file*/
  80. public FILE *open_source(LOC_FILE *lf,unsigned char *name,boolean top)
  81. { unsigned char f[256];
  82.  
  83.   lf->unlink_name=0;
  84.   if ((top?top_filter:source_filter)==0)
  85.    { lf->fp=fopen((char*)name,(char*)"r");
  86.      lf->pipe=0;
  87.    }
  88.   else
  89.      if (access((char*)name,R_OK))
  90.         lf->fp=0;
  91.      else
  92.       { ustrcpy(f,top?top_filter:source_filter);
  93.         strcat((char*)f," ");
  94.         ustrcat(f,name);
  95.         lf->fp=popen((char*)f,(char*)"r");
  96.         lf->pipe=True;
  97.       }
  98. # ifdef SETBUF
  99.      if (lf->fp) SETBUF(lf->fp);
  100. # endif
  101.   return (lf->fp);
  102. }
  103. /*}}}  */
  104. /*{{{  clear_file*/
  105. public void clear_file(LOC_FILE *f)
  106. { if (f->fp)
  107.      if (f->pipe)
  108.         pclose(f->fp);
  109.      else
  110.         fclose(f->fp);
  111.   if (f->unlink_name)
  112.      unlink((char*)f->unlink_name);
  113. }
  114. /*}}}  */
  115. /*{{{  kbd_exit*/
  116. public void kbd_exit(int ret)
  117. { clear_file(&rc);
  118.   clear_file(&bnd);
  119.   clear_file(&in);
  120.   clear_file(&ref);
  121.   clear_file(&ref_no);
  122.   exit(ret);
  123. }
  124. /*}}}  */
  125. /*{{{  kbd_malloc/free*/
  126. public void *kbd_malloc(size_t l)
  127. {
  128.   void *x;
  129.  
  130.   if (!(x=ORImalloc(l)))
  131.    { fprintf(stderr,M_NOMEMORY);
  132.      kbd_exit(1);
  133.    }
  134.   return(x);
  135. }
  136. public void kbd_free(void *x)
  137. {
  138.   ORIfree(x);
  139. }
  140. /*}}}  */
  141. /*{{{  write procedures*/
  142. /*{{{  write mark-type to rc*/
  143. public void write_mark_rc(unsigned char *name, unsigned char marks[4][FOLD_TAG_LENGTH+1])
  144. {
  145.   int i,j;
  146.   unsigned char *n=name;
  147.  
  148.   if (dest_mac)
  149.      return;
  150.   rc_put_c(RC_MARKS,rc.fp);
  151.   for (i=1;i<FOLD_PATTERN_LEN;i++)
  152.      if (*n!='\0')
  153.         rc_put_c(*n++,rc.fp);
  154.      else
  155.         rc_put_c('\0',rc.fp);
  156.   for (i=0;i<4;i++)
  157.      for (j=0;j<FOLD_TAG_LENGTH;j++)
  158.         rc_put_c(marks[i][j],rc.fp);
  159.   m_counter++;
  160.   if (verbose_level>0)
  161.      fprintf(stderr,F_MDECLARE,name);
  162. }
  163. /*}}}  */
  164. /*{{{  write binding_name to rc file*/
  165. public void write_name_rc(unsigned char *name)
  166. {
  167.   if (!dest_mac)
  168.      if (*name=='\0' || ustrlen(name)>BIND_NAME_LEN)
  169.         m_exit(M_NOBINDNAME);
  170.      else
  171.         ustrcpy(bnd_name,name);
  172. }
  173. /*}}}  */
  174. /*{{{  write one macro definition to rc file*/
  175. /*{{{  buffer for macro storage*/
  176. #ifndef MAC_BUFF_SIZE
  177. #  define MAC_BUFF_SIZE 0
  178. #endif
  179. private TOKEN mac_buff[OCL_CODE_LEN+secure_macro_lg+MAC_BUFF_SIZE+2];
  180. public TOKEN *mac_ptr=mac_buff+2;
  181. int mb_m_used=0;
  182. int mb_t_used=0;
  183. /*}}}  */
  184. /*{{{  mb_flush*/
  185. private void mb_flush(boolean full)
  186. {
  187.   if (mb_m_used)
  188.      if (full || mb_t_used+2*mb_m_used>MAC_BUFF_SIZE+2)
  189.       { TOKEN *t;
  190.         int i;
  191.  
  192.         rc_put_c(RC_MAC_SET,rc.fp);
  193.         rc_put_w(mb_t_used+mb_m_used,rc.fp);
  194.         for (t=mac_buff,i=mb_t_used+2*mb_m_used;i;i--,t++)
  195.            rc_put_w(*t,rc.fp);
  196.         mac_ptr=mac_buff+2;
  197.         mb_m_used=0;
  198.         mb_t_used=0;
  199.       }
  200. }
  201. /*}}}  */
  202.  
  203. public void write_macro_rc(int tag,TOKEN op,int lg,TOKEN *code,unsigned char *name)
  204. {
  205.   if (dest_mac && op!=O_EXE_MACRO)
  206.      return;
  207.   /*{{{  comment*/
  208.   if (name && *name && commenting)
  209.    { char *t="following macro is ";
  210.  
  211.      rc_put_c(RC_COMMENT,rc.fp);
  212.      while (*t) rc_put_c(*t++,rc.fp);
  213.      do
  214.         rc_put_c(*name,rc.fp);
  215.      while (*name++);
  216.    }
  217.   /*}}}  */
  218.   switch (tag)
  219.    { case RC_MAC_SET:
  220.         if (demand)
  221.            tag=RC_LOADMACRO;
  222.         else
  223.          /*{{{  add to buffer and maybe flush it*/
  224.          {
  225.            /*{{{  add mac to buffer*/
  226.            *(mac_ptr-2)=op;
  227.            *(mac_ptr-1)=lg;
  228.            mac_ptr+=lg+2;
  229.            mb_m_used++;
  230.            mb_t_used+=lg;
  231.            /*}}}  */
  232.            mb_flush(commenting);
  233.            /*{{{  verbose-mode*/
  234.            if (verbose_level>0)
  235.             { fprintf(stderr,F_STMAC,op,lg+1);
  236.               t_counter += lg+1;
  237.             }
  238.            /*}}}  */
  239.  
  240.            return;
  241.          }
  242.          /*}}}  */
  243.      case RC_INITMACRO:
  244.      case RC_LOADMACRO:
  245.         break;
  246.      default:
  247.        m_exit(M_NOMACROTAG);
  248.    }
  249.   /*{{{  verbose-mode*/
  250.   if (verbose_level>0)
  251.    { fprintf(stderr,(tag==RC_INITMACRO?F_DEMAC:F_LOMAC),op,lg+1);
  252.      t_counter += lg+1;
  253.      if (tag==RC_LOADMACRO)
  254.         tl_counter+=lg+1;
  255.    }
  256.   /*}}}  */
  257.   /*{{{  code*/
  258.   rc_put_c(tag,rc.fp);
  259.   rc_put_w(op,rc.fp);
  260.   rc_put_w(lg,rc.fp);
  261.   while (lg--) rc_put_w(*code++,rc.fp);
  262.   /*}}}  */
  263. }
  264. /*}}}  */
  265. /*{{{  write an usermodestring to rc*/
  266. public void write_ums_rc(int no,unsigned char *lo,unsigned char *sh)
  267. {
  268.   int i;
  269.  
  270.  
  271.   if (dest_mac)
  272.      return;
  273.  
  274.   /*{{{  cut length*/
  275.   lo[BIND_NAME_LEN]=sh[BIND_NAME_LEN]='\0';
  276.   /*}}}  */
  277.   /*{{{  lo==sh -> skip sh*/
  278.   if (!ustrcmp(lo,sh))
  279.      sh=(unsigned char*)"";
  280.   /*}}}  */
  281.   /*{{{  start mode field*/
  282.   rc_put_c(RC_MODE,rc.fp);
  283.   rc_put_c(no,rc.fp);
  284.   /*}}}  */
  285.   /*{{{  write long*/
  286.   rc_put_w(i=ustrlen(lo),rc.fp);
  287.   for (;i--;) rc_put_c(*lo++,rc.fp);
  288.   /*}}}  */
  289.   /*{{{  write short*/
  290.   rc_put_w(i=ustrlen(sh),rc.fp);
  291.   for (;i--;) rc_put_c(*sh++,rc.fp);
  292.   /*}}}  */
  293. }
  294. /*}}}  */
  295. /*{{{  write one definition to bind file*/
  296. public void write_bind(unsigned char const *name,unsigned char *code,int kbd)
  297. {
  298.   unsigned char tag[REF_TAG_LG+1];
  299.  
  300.   if (dest_mac) return;
  301.   name=cut_overload(name);
  302.   ref_code_tag((char*)tag,kbd);
  303.   fprintf
  304.    ( bnd.fp,
  305.      (kbd==mouse_kbd) ? ref_node_str("Mouse: %c") : ref_node_str("%s"),
  306.      tag,
  307.      ustrlen(name),
  308.      name,
  309.      code
  310.    );
  311. }
  312. /*}}}  */
  313. /*{{{  write_string*/
  314. public TOKEN write_string(TOKEN *t,int lg,boolean generate)
  315. {
  316.   static TOKEN tok=MSG_ARG_FORMAT+1;
  317.   struct RC_STR *x;
  318.  
  319.   x=kbd_malloc(sizeof(struct RC_STR)+lg+1);
  320.   /*{{{  copy string to node*/
  321.   { int i;
  322.  
  323.     x->text=(unsigned char*)((struct RC_STR*)x+1);
  324.     for (i=0;i<lg;i++)
  325.        x->text[i]=t[i];
  326.     x->text[lg]='\0';
  327.   }
  328.   /*}}}  */
  329.   /*{{{  check, if already defined*/
  330.   { struct RC_STR *s;
  331.  
  332.     for (s=rc_strings;s;s=s->next)
  333.        if (!ustrcmp(x->text,s->text))
  334.         { kbd_free(x);
  335.           return(s->ad);
  336.         }
  337.   }
  338.   /*}}}  */
  339.   if (!generate)
  340.    { kbd_free(x);
  341.      return(0);
  342.    }
  343.   /*{{{  insert in list of messages*/
  344.   rc_str_lg+=lg+1;
  345.   rc_str_count++;
  346.   x->next=rc_strings;
  347.   rc_strings=x;
  348.   x->ad=tok++;
  349.   /*}}}  */
  350.   if (verbose_level>0)
  351.      fprintf(stderr,F_STRING,x->text,x->ad);
  352.  
  353.   return(x->ad);
  354. }
  355. /*}}}  */
  356. /*{{{  write rc-constants*/
  357. public void put_consts(void)
  358. {
  359.   static off_t offset = (off_t)-1;
  360.   off_t current=(off_t)-1;
  361.   int i;
  362.  
  363.   if (dest_mac)
  364.      return;
  365.   /*{{{  handle position for const block*/
  366.   if (offset==(off_t)-1)
  367.    /*{{{  store position*/
  368.      offset=ftell(rc.fp);
  369.    /*}}}  */
  370.   else
  371.    /*{{{  store current and seek to first*/
  372.    { current=ftell(rc.fp);
  373.      fseek(rc.fp,offset,SEEK_SET);
  374.    }
  375.    /*}}}  */
  376.   /*}}}  */
  377.   /*{{{  write entry*/
  378.   rc_put_c(RC_CONST,rc.fp);
  379.   for (i=0;i<RCC_SIZE;i++)
  380.      rc_put_w(bind_const[i],rc.fp);
  381.   for (i=0;i<BIND_NAME_LEN;i++)
  382.      rc_put_c(bnd_name[i],rc.fp);
  383.   for (i=0;i<NO_OCL_CMD_OPTS*(2*BIND_NAME_LEN+2);i++)
  384.      rc_put_c(ocl_opts[i],rc.fp);
  385.   /*}}}  */
  386.   /*{{{  maybe jump back*/
  387.   if (current!=(off_t)-1)
  388.      fseek(rc.fp,current,SEEK_SET);
  389.   /*}}}  */
  390.   /*{{{  write all missing macros*/
  391.   mb_flush(True);
  392.   /*}}}  */
  393.   if (rc_strings)
  394.    { rc_put_c(RC_STRINGS,rc.fp);
  395.      rc_put_w(rc_str_count,rc.fp);
  396.      rc_put_w(rc_str_lg,rc.fp);
  397.      while (rc_str_count--)
  398.       { char *s;
  399.         struct RC_STR *x;
  400.  
  401.         for (s=(char*)rc_strings->text;*s;s++)
  402.            rc_put_c(*s,rc.fp);
  403.         rc_put_c('\0',rc.fp);
  404.         x=rc_strings->next;
  405.         kbd_free(rc_strings);
  406.         rc_strings=x;
  407.       }
  408.      rc_str_lg=0;
  409.    }
  410. }
  411. /*}}}  */
  412. /*{{{  write one macro coded to stdout*/
  413. public void write_dest_mac (TOKEN *b,int lg)
  414. {
  415.   write_macro_rc(RC_INITMACRO,O_EXE_MACRO,lg,b,(unsigned char*)0);
  416.   rc_put_c(RC_ENDE,rc.fp);
  417. }
  418. /*}}}  */
  419. /*{{{  write mousebutton-mapping to rc*/
  420. public void write_buttons_rc(TOKEN*map,int buttons)
  421. {
  422.   int i;
  423.  
  424.   if (dest_mac) return;
  425.   rc_put_c(RC_M_TAB,rc.fp);
  426.   rc_put_w(buttons,rc.fp);
  427.   for (i=0;i<buttons;i++) rc_put_w(map[i],rc.fp);
  428.   if (verbose_level>0) fprintf(stderr,F_M_USE,m_name,buttons);
  429. }
  430. /*}}}  */
  431. /*{{{  rc_app_help*/
  432. /*{{{  compress_and_print_help*/
  433. private unsigned int compress_and_print_help(unsigned char *saved_line)
  434. {
  435.   if (do_opt)
  436.    { unsigned char *line;
  437.  
  438.      for (line=saved_line;;)
  439.       { switch(*line++)
  440.          { case REF_NODE_LIMITER:
  441.               ref_compress_text(line);
  442.            case '\0':
  443.               break;
  444.            default:
  445.               continue;
  446.          }
  447.         break;
  448.       }
  449.    }
  450.   fputs((char*)saved_line,rc.fp);
  451.  
  452.   return(ustrlen(saved_line));
  453. }
  454. /*}}}  */
  455.  
  456. private boolean rc_app_help(unsigned char *filename,boolean add_tag,boolean f_unlink)
  457. {
  458.   /*{{{  variables*/
  459.   FILE *f;
  460.   int c;
  461.   unsigned char line_buff[RC_HELP_LEN+2];
  462.   unsigned char saved_line_buff[RC_HELP_LEN+2];
  463.   unsigned char *l0;
  464.   int lines;
  465.   int pre_c_size=0,post_c_size=0;
  466.   /*}}}  */
  467.  
  468.   if (!(f=fopen((char*)filename,(char*)"rb")))
  469.      return(True);
  470. # ifdef SETBUF
  471.      SETBUF(f);
  472. # endif
  473.   saved_line_buff[0]='\0';
  474.   l0=line_buff;
  475.   if (add_tag)
  476.    /*{{{  generate reference tag in front of line*/
  477.    { ref_code_tag((char*)line_buff,ref_kbd);
  478.      while (*l0)
  479.         l0++;
  480.      *l0++=REF_NODE_LIMITER;
  481.    }
  482.    /*}}}  */
  483.   *l0='\0';
  484.   for
  485.    ( lines= -1,
  486.      saved_line_buff[0]='\0'
  487.    ; !feof(f)
  488.    ; lines++
  489.    )
  490.    {
  491.      /*{{{  read one line of data*/
  492.      { unsigned char *lx;
  493.  
  494.        for(lx=l0;;)
  495.         { c=fgetc(f);
  496.           if (c=='\n' || c==EOF)
  497.            { *lx='\0';
  498.              pre_c_size+=(lx-line_buff);
  499.              break;
  500.            }
  501.           else if (lx<l0+RC_HELP_LEN)
  502.            { if (c>=' ')
  503.                 *lx++=c;
  504.              else
  505.               { *lx++='^';
  506.                 if (lx<l0+RC_HELP_LEN)
  507.                    *lx++=CTRL_CHARS[c];
  508.               }
  509.  
  510.            }
  511.         }
  512.      }
  513.      /*}}}  */
  514.      /*{{{  cut trailing spaces*/
  515.      { unsigned char *s,*y;
  516.  
  517.        for (y=line_buff;*y && *y++!=REF_NODE_LIMITER;);
  518.        for (s=y;;)
  519.         { switch (*s++)
  520.            { default:
  521.                 y=s;
  522.              case ' ':
  523.                 continue;
  524.              case '\n':
  525.              case '\0':
  526.                 break;
  527.            }
  528.           break;
  529.         }
  530.        *y++='\n';
  531.        *y='\0';
  532.      }
  533.      /*}}}  */
  534.      if (line_buff[0]!='\0' && line_buff[0]!='\n')
  535.       /*{{{  store this line*/
  536.       { if (saved_line_buff[0])
  537.          /*{{{  print saved line or alias*/
  538.          { if (do_opt)
  539.             { unsigned char *o,*n;
  540.  
  541.               /*{{{  skip old tag*/
  542.               for (o=saved_line_buff;*o && *o!=REF_NODE_LIMITER;o++);
  543.               /*}}}  */
  544.               /*{{{  skip new tag*/
  545.               for (n=line_buff;*n && *n!=REF_NODE_LIMITER;n++);
  546.               /*}}}  */
  547.               if
  548.                /*{{{  same text, different tags and alias shorter than text*/
  549.                (    (!ustrcmp(o,n))
  550.                  && (ustrlen(n)>(n-line_buff))
  551.                  && (ustrcmp(saved_line_buff,line_buff))
  552.                )
  553.                /*}}}  */
  554.                /*{{{  change old data to link*/
  555.                { *o++=REF_NODE_ALIAS;
  556.                  for (n=line_buff;*n!=REF_NODE_LIMITER;*o++ = *n++);
  557.                  *o++='\n';
  558.                  *o='\0';
  559.                }
  560.                /*}}}  */
  561.             }
  562.            post_c_size+=compress_and_print_help(saved_line_buff);
  563.          }
  564.          /*}}}  */
  565.         ustrcpy(saved_line_buff,line_buff);
  566.       }
  567.       /*}}}  */
  568.    }
  569.   if (saved_line_buff[0])
  570.      post_c_size+=compress_and_print_help(saved_line_buff);
  571.   /*{{{  verbose*/
  572.   if (verbose_level>0 && lines)
  573.      if (do_opt)
  574.         fprintf
  575.          ( stderr,
  576.            "appended %s %d lines as help (compressed to %d%%).\n",
  577.            filename,
  578.            lines,
  579.            (100*post_c_size)/pre_c_size
  580.          );
  581.      else
  582.         fprintf(stderr,"appended %s %d lines as help.\n",filename,lines);
  583.   /*}}}  */
  584.   if (fclose(f))
  585.    { fprintf(stderr,F_CLOSE,filename);return(True); }
  586.  
  587.   return(f_unlink && unlink((char*)filename));
  588. }
  589. /*}}}  */
  590. /*}}}  */
  591.  
  592. /*{{{  main*/
  593. int main(int argc,char **argv)
  594. {
  595.   /*{{{  variable declarations*/
  596.   unsigned char
  597.        refname[_POSIX_PATH_MAX],
  598.        refname_no[_POSIX_PATH_MAX],
  599.        tmpbind[_POSIX_PATH_MAX],
  600.        rcfile[_POSIX_PATH_MAX],
  601.        bindfile[_POSIX_PATH_MAX];
  602.   unsigned char *filebase=std_basename;
  603.   boolean crashed;
  604.   /*}}}  */
  605.  
  606.   /*{{{  init*/
  607.   refname[0]='\0';
  608.   init_alias();
  609.   init_sets();
  610.   signal(SIGTERM,kbd_exit);
  611.   signal(SIGHUP,kbd_exit);
  612.   signal(SIGINT,kbd_exit);
  613.   signal(SIGQUIT,kbd_exit);
  614.   if (!(lib_path=getenv(KBDPATH)) && !(lib_path=getenv(KBDPATH_1)))
  615.      lib_path=KBD_PATH;
  616.   /*}}}  */
  617.   /*{{{  parse arguments*/
  618.   { int c;
  619.  
  620.     /*{{{  Notes*/
  621.     /* This is the first version which uses getopt, so the code is still suboptimal. */
  622.     /*}}}  */
  623.     while ((c=getopt(argc,argv,"cf:h?lo:sdvwr:F:ORm:M:U:L:V:"))!=EOF)
  624.     switch (c)
  625.     {
  626.       /*{{{  f filter*/
  627.       case 'f':
  628.          top_filter=source_filter=(*optarg?(unsigned char*)optarg:(unsigned char*)0); break;
  629.       /*}}}  */
  630.       /*{{{  h, ?*/
  631.       case '?':
  632.       case 'h':
  633.          do_usage();
  634.          kbd_exit(0);
  635.       /*}}}  */
  636.       /*{{{  l*/
  637.       case 'l':
  638.       {
  639.         sc_list_keys();
  640.         kbd_exit(0);
  641.         break;
  642.       }
  643.       /*}}}  */
  644.       /*{{{  c*/
  645.       case 'c':
  646.       { commenting=True;
  647.         break;
  648.       }
  649.       /*}}}  */
  650.       /*{{{  o name*/
  651.       case 'o':
  652.        { static unsigned char new_out[_POSIX_PATH_MAX];
  653.  
  654.          strcpy((char*)(filebase=new_out),optarg);
  655.          home_expand((char*)filebase);
  656.          break;
  657.        }
  658.       /*}}}  */
  659.       /*{{{  s*/
  660.       case 's': sorting=True; break;
  661.       /*}}}  */
  662.       /*{{{  d*/
  663.       case 'd': new_vars_enabled=True; break;
  664.       /*}}}  */
  665.       /*{{{  v*/
  666.       case 'v': verbose_level=1; break;
  667.       /*}}}  */
  668.       /*{{{  w*/
  669.       case 'w': warning=True; break;
  670.       /*}}}  */
  671.       /*{{{  r name*/
  672.       case 'r':
  673.          strcpy((char*)refname,optarg);
  674.          home_expand((char*)refname);
  675.          break;
  676.       /*}}}  */
  677.       /*{{{  F filter*/
  678.       case 'F': top_filter= *optarg?(unsigned char*)optarg:(unsigned char*)0;source_filter=0; break;
  679.       /*}}}  */
  680.       /*{{{  L libpath*/
  681.       case 'L': lib_path=optarg;break;
  682.       /*}}}  */
  683.       /*{{{  O*/
  684.       case 'O': do_opt=True; break;
  685.       /*}}}  */
  686.       /*{{{  R*/
  687.       case 'R': rcref=True; break;
  688.       /*}}}  */
  689.       /*{{{  m macro*/
  690.       case 'm': dest_mac=(unsigned char*)optarg; break;
  691.       /*}}}  */
  692.       /*{{{  M name*/
  693.       case 'M': m_name=(unsigned char*)optarg; break;
  694.       /*}}}  */
  695.       /*{{{  U tag*/
  696.       case 'U': use_it((unsigned char*)optarg); break;
  697.       /*}}}  */
  698.       /*{{{  V level*/
  699.       case 'V': verbose_level=atoi(optarg); break;
  700.       /*}}}  */
  701.     }
  702.   }
  703.   if (verbose_level>0)
  704.      warning=True;
  705.   /*}}}  */
  706.   /*{{{  check lib path*/
  707.     { char *k;
  708.       char c;
  709.  
  710.       k=lib_path;
  711.       while ((c = *k++))
  712.          if
  713.           (    ((c==LIST_C)||(c==LIST_C_1))
  714.             && (((c = *k)==LIST_C)||(c==LIST_C_1)||(c=='\0'))
  715.           )
  716.           { fprintf(stderr,F_INV_PATH,lib_path);
  717.             exit(1);
  718.           }
  719.     }
  720.   /*}}}  */
  721.   /*{{{  init keytabs*/
  722.   init_keytables();
  723.   /*}}}  */
  724.   /*{{{  init @use*/
  725.   default_using();
  726.   /*}}}  */
  727.   /*{{{  init compression data*/
  728.   if (ref_init_comp_data(1))
  729.      m_exit(M_NOMEMORY);
  730.   /*}}}  */
  731.   /*{{{  open files/pipe*/
  732.   /*{{{  open reference files*/
  733.   if (!dest_mac)
  734.    {
  735.      /*{{{  refcard file*/
  736.      ref.unlink_name=0;
  737.      ref.pipe=False;
  738.      if (rcref && !refname[0])
  739.       { tmpnam((char*)refname);
  740.         ref.unlink_name=refname;
  741.       }
  742.      if (refname[0] && (ref.fp=fopen((char*)refname,(char*)"w"))==(FILE*)0)
  743.         m_exit(M_NOREF);
  744. #       ifdef SETBUF
  745.            SETBUF(ref.fp);
  746. #       endif
  747.      /*}}}  */
  748.      /*{{{  numbered refcard file*/
  749.      ref_no.unlink_name=0;
  750.      ref_no.pipe=False;
  751.      tmpnam((char*)refname_no);
  752.      ref.unlink_name=refname_no;
  753.      if
  754.       (    refname_no[0]
  755.         && !(ref_no.fp=fopen((char*)refname_no,(char*)"w"))
  756.       )
  757.         m_exit(M_NOREF);
  758. #       ifdef SETBUF
  759.            SETBUF(ref_no.fp);
  760. #       endif
  761.      /*}}}  */
  762.    }
  763.   /*}}}  */
  764.   /*{{{  open input-file*/
  765.   if (optind>=argc)
  766.    { do_usage();
  767.      kbd_exit(1);
  768.    }
  769.   if (open_source(&in,(unsigned char*)argv[optind],True)==(FILE*)0)
  770.      m_exit(M_NOBFILE);
  771.   source=(unsigned char*)argv[optind];
  772.   init_scan();
  773.   /*}}}  */
  774.   /*{{{  open .origamirc*/
  775.   rc.pipe=False;
  776.   rc.unlink_name=0;
  777.   if (dest_mac)
  778.      rc.fp=stdout;
  779.   else if ((rc.fp=fopen((char*)completebase(rcfile,filebase,(unsigned char*)RC_ENDING),(char*)"wb"))==(FILE*)0)
  780.      m_exit(F_NORC,filebase);
  781. #  ifdef SETBUF
  782.      SETBUF(rc.fp);
  783. #  endif
  784.   /*}}}  */
  785.   /*{{{  open .origamibind*/
  786.   tmpnam((char*)tmpbind);
  787.   if (!dest_mac)
  788.    { if (!sorting)
  789.       /*{{{  open file*/
  790.       { bnd.pipe=False;
  791.         bnd.unlink_name=tmpbind;
  792.         if ((bnd.fp=fopen((char*)tmpbind,(char*)"w"))==(FILE*)0)
  793.            m_exit(F_NOBIND,tmpbind);
  794.       }
  795.       /*}}}  */
  796.      else
  797.       /*{{{  open pipe*/
  798.       { bnd.pipe=True;
  799.         bnd.unlink_name=tmpbind;
  800.         sprintf((char*)bindfile,SORTCMD,(char*)tmpbind);
  801.         if ((bnd.fp=popen((char*)bindfile,(char*)"w"))==(FILE*)0)
  802.            m_exit(F_NOPIPE,bindfile);
  803.       }
  804.       /*}}}  */
  805. #    ifdef SETBUF
  806.         SETBUF(bnd.fp);
  807. #    endif
  808.    }
  809.   /*}}}  */
  810.   /*}}}  */
  811.   if (dest_mac) verbose_level=0;
  812.   crashed=process_file();
  813.   if (!crashed && !dest_mac)
  814.    /*{{{  handle bind*/
  815.    { ref_put_comp_data(rc.fp);
  816.      if (sorting ? pclose(bnd.fp) : fclose(bnd.fp))
  817.       { bnd.fp=0;
  818.         m_exit(F_CLOSE,"bindfile");
  819.       }
  820.      else
  821.       { rc_put_c(RC_BIND,rc.fp);
  822.         if (rc_app_help(tmpbind,False,True))
  823.          { fprintf(stderr,F_NOBIND,tmpbind);
  824.            crashed=True;
  825.          }
  826.       }
  827.    }
  828.    /*}}}  */
  829.   else
  830.    /*{{{  close bind*/
  831.      clear_file(&bnd);
  832.    /*}}}  */
  833.   /*{{{  close ref*/
  834.   if (ref.fp && fclose(ref.fp))
  835.    { crashed=True;
  836.      fprintf(stderr,F_CLOSE,refname);
  837.      ref.fp=0;
  838.    }
  839.   /*}}}  */
  840.   /*{{{  close ref_no*/
  841.   if (ref_no.fp && fclose(ref_no.fp))
  842.    { crashed=True;
  843.      fprintf(stderr,F_CLOSE,refname_no);
  844.      ref_no.fp=0;
  845.    }
  846.   /*}}}  */
  847.   /*{{{  maybe copy ref to rc*/
  848.   if (!dest_mac && !crashed)
  849.    { if (rcref)
  850.       { char pseudo_ref[8];
  851.  
  852.         ref_code_tag(pseudo_ref,-ref_file_id);
  853.         fprintf(rc.fp,ref_format_str("r-file"),pseudo_ref);
  854.         crashed=rc_app_help(refname,True,ref.unlink_name!=0);
  855.       }
  856.      if (!crashed)
  857.       { char pseudo_ref[8];
  858.  
  859.         ref_code_tag(pseudo_ref,-ref_class_id);
  860.         fprintf(rc.fp,ref_format_str("r-class"),pseudo_ref);
  861.         crashed=rc_app_help(refname_no,False,True);
  862.       }
  863.      if (!crashed && !rcref)
  864.       { char pseudo_ref[8];
  865.  
  866.         ref_code_tag(pseudo_ref,-ref_file_id);
  867.         fprintf(rc.fp,ref_format_str("r-file"),pseudo_ref);
  868.       }
  869.    }
  870.   /*}}}  */
  871.   /*{{{  close rc and in and unlink tmp*/
  872.   clear_file(&in);
  873.   if (!dest_mac && fclose(rc.fp))
  874.    { fprintf(stderr,F_CLOSE,"rc-file");
  875.      crashed=True;
  876.    }
  877.   rc.fp=0;
  878.   /*}}}  */
  879.   /*{{{  maybe message*/
  880.   if (crashed)
  881.      m_exit(M_INCORRECTFILES);
  882.   else if (verbose_level>0)
  883.    { fprintf(stderr,F_INTS,var_count);
  884.      fprintf(stderr,F_BINDS,t_counter,t_counter-tl_counter,tl_counter);
  885.      fprintf(stderr,F_MARKT,m_counter);
  886.      fprintf(stderr,F_MOUSE,m_name);
  887.    }
  888.   /*}}}  */
  889.   kbd_exit(0);
  890. }
  891. /*}}}  */
  892.